/*
 * Copyright 2022. Huawei Technologies Co., Ltd. All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.huawei.mlkit.test.example.language.textner;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hms.mlsdk.common.MLApplication;
import com.huawei.hms.mlsdk.common.MLException;
import com.huawei.hms.mlsdk.entity.MLNerFactory;
import com.huawei.hms.mlsdk.entity.cloud.MLRemoteNer;
import com.huawei.hms.mlsdk.entity.cloud.MLRemoteNerSetting;
import com.huawei.hms.mlsdk.entity.cloud.bo.RemoteNerResultItem;
import com.huawei.mlkit.test.example.ChooseActivity;
import com.huawei.mlkit.test.example.R;

/**
 * TextNerActivity
 *
 * @since 2022-08-22
 */
public class TextNerActivity extends AppCompatActivity {
    private static final String TAG = TextNerActivity.class.getSimpleName();

    private ExecutorService mExecutorService;
    private EditText etInput;
    private EditText etOutput;
    private Button btnNer;
    private RadioGroup radioGroup;
    private RadioButton radioButSyn;
    private RadioButton radioButAsyn;
    private boolean isSync = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_ner);
        // Set ApiKey.
        MLApplication.getInstance().setApiKey(ChooseActivity.apiKey);
        mExecutorService = Executors.newSingleThreadExecutor();
        initView();
        initEventListener();
    }

    private void initView() {
        etInput = (EditText) findViewById(R.id.et_input);
        etOutput = (EditText) findViewById(R.id.et_output);
        btnNer = (Button) findViewById(R.id.btn_ner);

        radioGroup = (RadioGroup) findViewById(R.id.radio_group);
        radioButSyn = (RadioButton) findViewById(R.id.radio_but_syn);
        radioButAsyn = (RadioButton) findViewById(R.id.radio_but_asyn);
    }

    private void initEventListener() {
        btnNer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String sourceText = getInputText();
                if (sourceText.isEmpty()) {
                    updateOutputText("The input text cannot be empty.");
                    return;
                }
                nerCloud(sourceText);
            }
        });

        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (group.getCheckedRadioButtonId()) {
                    case R.id.radio_but_syn:
                        isSync = true;
                        break;
                    case R.id.radio_but_asyn:
                        isSync = false;
                        break;
                    default:
                        break;
                }
            }
        });
    }

    private void updateOutputText(final String text) {
        if (text == null) {
            throw new IllegalArgumentException("text is null");
        }

        if (text.isEmpty()) {
            Log.w(TAG, "updateOutputText: text is empty");
            return;
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                etOutput.setText(text);
            }
        });
    }

    private String getInputText() {
        return etInput.getText().toString().trim();
    }

    private void nerCloud(final String input) {
        Log.i(TAG, "entityCloud");
        MLRemoteNerSetting setting = new MLRemoteNerSetting.Factory()
                .setSourceLangCode("zh")
                .create();
        MLRemoteNer ner = MLNerFactory.getInstance().getRemoteNer(setting);
        if (isSync) {
            Log.i(TAG, "entityCloud call sync fun");
            mExecutorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        RemoteNerResultItem[] remoteNerResultItems = ner.syncEntityExtract(input);
                        showToast("entityCloud success");
                        if (remoteNerResultItems != null) {
                            StringBuffer buffer = new StringBuffer();
                            for (RemoteNerResultItem item : remoteNerResultItems) {
                                buffer.append("[").append("entityWord：" + item.getEntity() + " entityType：" + item.getType() + " startSpan：" + item.getMention()).append("]").append(";").append("\n");
                            }
                            Log.i(TAG, "entityCloud result: " + buffer);
                            updateOutputText(buffer.toString());
                        } else {
                            updateOutputText("The recognition result is empty.");
                        }
                    } catch (MLException e) {
                        Log.i(TAG, "entityCloud failed: " + e.getMessage());
                        updateOutputText(e.getMessage());
                    }
                }
            });
        } else {
            Log.i(TAG, "entityCloud call async fun");
            ner.asyncEntityExtract(input).addOnSuccessListener(new OnSuccessListener<RemoteNerResultItem[]>() {
                @Override
                public void onSuccess(RemoteNerResultItem[] remoteNerResultItems) {
                    showToast("entityCloud success");
                    if (remoteNerResultItems != null) {
                        StringBuffer buffer = new StringBuffer();
                        for (RemoteNerResultItem item : remoteNerResultItems) {
                            buffer.append("[").append("entityWord：" + item.getEntity() + " entityType：" + item.getType() + " startSpan：" + item.getMention()).append("]").append(";").append("\n");
                        }
                        Log.i(TAG, "entityCloud result: " + buffer);
                        updateOutputText(buffer.toString());
                    } else {
                        updateOutputText("The recognition result is empty.");
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(Exception e) {
                    Log.i(TAG, "entityCloud failed: " + e.getMessage());
                    updateOutputText(e.getMessage());
                }
            });
        }
    }

    // 弹出消息封装
    private void showToast(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
                toast.show();
            }
        });
    }
}